home *** CD-ROM | disk | FTP | other *** search
- From: ihnp4!think!massar (JP Massar)
- Subject: rolodex database program -- part 3 of 3
- Newsgroups: mod.sources
- Approved: jpn@panda.UUCP
-
- Mod.sources: Volume 4, Issue 29
- Submitted by: ihnp4!think!massar (JP Massar)
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # toolsdir
- # This archive created: Thu Mar 13 18:29:56 1986
- export PATH; PATH=/bin:$PATH
- if test ! -d 'toolsdir'
- then
- echo shar: creating directory "'toolsdir'"
- mkdir 'toolsdir'
- fi
- echo shar: extracting "'toolsdir/Makefile'" '(143 characters)'
- if test -f 'toolsdir/Makefile'
- then
- echo shar: will not over-write existing file "'toolsdir/Makefile'"
- else
- cat << \SHAR_EOF > 'toolsdir/Makefile'
- CC = cc
- CFLAGS = -DBSD42 -O
- DBGFLAG =
- SOURCES = mem.c ctools.c args.c menu.c
- OBJECTS = mem.o ctools.o args.o menu.o
- LIBS =
-
- tools: $(OBJECTS)
- SHAR_EOF
- if test 143 -ne "`wc -c < 'toolsdir/Makefile'`"
- then
- echo shar: error transmitting "'toolsdir/Makefile'" '(should have been 143 characters)'
- fi
- fi
- echo shar: extracting "'toolsdir/args.c'" '(8623 characters)'
- if test -f 'toolsdir/args.c'
- then
- echo shar: will not over-write existing file "'toolsdir/args.c'"
- else
- cat << \SHAR_EOF > 'toolsdir/args.c'
- #include <stdio.h>
- #include <ctype.h>
- #include "basics.h"
- #include "args.h"
- #include "sys5.h"
-
- /***************************************************************************/
- /***************************************************************************/
-
- /***** COMMAND LINE ARGUMENT PARSER *****/
-
- /***************************************************************************/
- /***************************************************************************/
-
- /* Author: JP Massar */
-
- /* parses command line arguments in argv under the following rules: */
- /* any argument not beginning with '-' is treated as a unit. */
- /* any argument beginning with a '-' must have the remaining characters */
- /* be in the set {a-zA-Z}. Each character is considered a separate option. */
- /* (Thus -abc is equivalent to -a -b -c). Non-dashed arguments are */
- /* associated with the option that precedes them, e.g, 'cat -a foo -b bar' */
- /* has foo associated with 'a' and bar associated with 'b'. A non-dashed */
- /* argument preceding any option is not associated with any option. */
- /* users can specify whether duplicate options are errors. */
-
- /* Non-dashed arguments are henceforth referred to as arguments, and */
- /* dashed arguments are henceforth referred to as options. */
- /* Arguments are ordered from left to right. */
-
- /* The following routines are available to users: */
-
- /* get_args() called to parse argv. Detects syntactic errors */
- /* any_option_present() are any options present in the command line? */
- /* option_present() is an option present? */
- /* option_arg() returns an argument associated with an option */
- /* non_option_arg() returns an argument not associated with any option */
- /* non_dash_arg() returns an argument */
- /* n_option_args() returns number of args associated with an option */
- /* n_non_option_args() rtns number of args not associated with any option */
- /* n_non_dash_args() returns number of arguments. */
- /* check_option_args() checks bounds on number of args assoc with an option */
- /* legal_options() checks that options provided are a subset of a-zA-Z */
- /* set_option() turns on option */
- /* error_message() prints out an illegal syntax error message to stderr */
-
-
- int option_to_index (achar) char achar;
- {
- if (isupper(achar)) return(achar - 'A');
- if (islower(achar)) return(achar - 'a' + 26);
- return(NO_OPTION);
- }
-
- char index_to_option (index) int index;
- {
- if (index < 26) return('A' + index);
- return('a' + index - 26);
- }
-
-
- /* the command line arguments are parsed into Cmd when get_args returns */
- /* successfully */
-
- static Ptr_Cmd_Line Cmd = NIL;
-
- int get_args (argc, argv, dup_error, print_msg)
-
- /* Returns one of NO_ARGS, ARG_ERROR, or ARGS_PRESENT */
-
- int argc;
- char **argv;
- Bool print_msg, dup_error;
-
- {
- int i,j,dash_index;
- Ptr_Cmd_Arg arg,last = NIL;
- char echar, *optr;
-
- Cmd = (Ptr_Cmd_Line) malloc(sizeof(Cmd_Line));
- Cmd -> non_dash_arg_list = NIL;
- for (j = 0; j < MAX_OPTIONS; j++) (Cmd -> dash_options)[j] = F;
-
- if (argc == 1) return(NO_ARGS);
-
- i = 0;
- dash_index = NO_OPTION;
-
- while (++i < argc) {
-
- /* parse arguments (i.e., anything not beginning with '-' */
-
- if (argv[i][0] != '-') {
- arg = (Ptr_Cmd_Arg) malloc(sizeof(Cmd_Arg));
- arg -> option = argv[i];
- arg -> option_index = dash_index;
- arg -> next = NIL;
- if (last == NIL) {
- Cmd -> non_dash_arg_list = arg;
- last = arg;
- }
- else {
- last -> next = arg;
- last = arg;
- }
- continue;
- }
-
- /* parse options. '-' by itself is illegal syntax */
-
- if (strlen(argv[i]) < 2) {
- echar = '-';
- goto parse_error;
- }
- optr = argv[i];
- optr++;
- while (*optr != '\0') {
- if (NO_OPTION == (dash_index = option_to_index(*optr))) {
- echar = *optr;
- goto parse_error;
- };
- if ((Cmd -> dash_options)[dash_index] && dup_error) {
- echar = *optr;
- goto duplicate_error;
- }
- (Cmd -> dash_options)[dash_index] = T;
- optr++;
- }
-
- }
-
- return(ARGS_PRESENT);
-
- parse_error :
-
- if (print_msg) fprintf(stderr,"illegal option: %c\n",echar);
- return(ARG_ERROR);
-
- duplicate_error:
-
- if (print_msg) fprintf(stderr,"duplicate option: %c\n",echar);
- return(ARG_ERROR);
-
- }
-
-
- Bool option_present (achar) char achar;
- {
- return((Cmd -> dash_options)[option_to_index(achar)]);
- }
-
-
- Bool any_option_present ()
- {
- int j;
- for (j = 0; j < MAX_OPTIONS; j++) {
- if ((Cmd -> dash_options)[j]) return(T);
- }
- return(F);
- }
-
-
- char * get_option_arg (i,n) int i; int n;
-
- /* get the nth option associated with the option whose index is 'i' */
-
- {
- int count;
- Ptr_Cmd_Arg args;
- args = Cmd -> non_dash_arg_list;
- count = 0;
- while (args != NIL) {
- if (i == args -> option_index && ++count == n) {
- return(args -> option);
- }
- args = args -> next;
- }
- return(NIL);
- }
-
-
- char * option_arg (achar,n) char achar; int n;
- {
- return(get_option_arg(option_to_index(achar),n));
- }
-
-
- char * non_option_arg (n) int n;
- {
- return(get_option_arg(NO_OPTION,n));
- }
-
-
- char * non_dash_arg (n) int n;
-
- {
- int count = 0;
- Ptr_Cmd_Arg arg;
- arg = Cmd -> non_dash_arg_list;
- while (arg != NIL) {
- if (++count == n) return(arg -> option);
- arg = arg -> next;
- }
- return(NIL);
- }
-
- print_args ()
-
- /* debugging routine which prints out the Cmd structure in readable form */
-
- {
- int j,i,n;
- char *option,ochar;
-
- if (Cmd == NIL) {
- printf("\n\nNo arguments\n\n");
- return;
- }
-
- printf("\n\narguments not associated with options: ");
- n = 1;
- while (T) {
- if (NIL == (option = non_option_arg(n++))) break;
- printf("%s ",option);
- }
- printf("\n");
-
- printf("\n\noptions and their arguments:\n\n");
- for (j = 0; j < MAX_OPTIONS; j++) {
- ochar = index_to_option(j);
- if (option_present(ochar)) {
- printf("%c : \t",ochar);
- i = 1;
- while (T) {
- if (NIL == (option = option_arg(ochar,i++))) break;
- printf("%s ",option);
- }
- printf(" \t(# is %d)",n_option_args(ochar));
- printf("\n");
- }
- }
-
- printf("\nnumber of non-dashed args is: %d\n",n_non_dash_args());
- printf("number of non-option args is : %d\n",n_non_option_args());
-
- }
-
-
- #define ALL -1
- #define NON_OPTION -2
-
- int arg_counter (type) int type;
-
- /* general routine which counts arguments */
- /* if type isn't ALL or NON_OPTION then type is an index of an option */
-
- {
- int index,count;
- Ptr_Cmd_Arg arg;
- arg = Cmd -> non_dash_arg_list;
- count = 0;
- index = (type == NON_OPTION) ? NO_OPTION : type;
- while (arg != NIL) {
- if (type == ALL) {
- count++;
- }
- else if (arg -> option_index == index) count++;
- arg = arg -> next;
- }
- return(count);
- }
-
- int n_option_args (achar) char achar;
- {
- return(arg_counter(option_to_index(achar)));
- }
-
- int n_non_option_args ()
- {
- return(arg_counter(NON_OPTION));
- }
-
- int n_non_dash_args ()
- {
- return(arg_counter(ALL));
- }
-
-
- set_option (achar) char achar;
- {
- (Cmd -> dash_options)[option_to_index(achar)] = T;
- }
-
-
- error_message (progname, argv, i, usage)
- char *progname; char ** argv; int i; char *usage;
- {
- fprintf(stderr,"\nillegal argument to %s : %s\n",progname,argv[i]);
- if (usage) fprintf(stderr,"%s\n",usage);
- }
-
-
- Bool
- check_option_args (achar,themin,themax) char achar; int themin,themax;
- {
- int n;
- if (themin > themax) return(T);
- n = n_option_args(achar);
- return ((Bool) (n >= themin && n <= themax));
- }
-
-
- char legal_options (legalstring) char *legalstring;
-
- /* are all the options the user specified characters in legalstring? */
- /* returns ALL_LEGAL if so, otherwise the first option not in the string */
-
- {
- int j;
- char option, *s;
- for (j = 0; j < MAX_OPTIONS; j++) {
- if ((Cmd -> dash_options)[j]) {
- option = index_to_option(j);
- s = legalstring;
- while (T) {
- if (*s == '\0') return(option);
- if (*s == option) break;
- s++;
- }
- }
- }
- return(ALL_LEGAL);
- }
- SHAR_EOF
- if test 8623 -ne "`wc -c < 'toolsdir/args.c'`"
- then
- echo shar: error transmitting "'toolsdir/args.c'" '(should have been 8623 characters)'
- fi
- fi
- echo shar: extracting "'toolsdir/args.h'" '(2401 characters)'
- if test -f 'toolsdir/args.h'
- then
- echo shar: will not over-write existing file "'toolsdir/args.h'"
- else
- cat << \SHAR_EOF > 'toolsdir/args.h'
- /* You must include "basics.h" to use this */
-
- /* To use this package, first call get_args, then call the various other */
- /* routines to see which options were given, etc. */
-
- #define NIL 0 /* null pointer */
-
- #define ARG_ERROR -1
- #define NO_ARGS 0
- #define ARGS_PRESENT 1
-
- #define MAX_OPTIONS 52 /* a-z A-Z */
- #define NO_OPTION -1
-
- /* an argument and the option it is associated with */
-
- typedef struct argument {
- char *option;
- int option_index;
- struct argument *next;
- } Cmd_Arg, *Ptr_Cmd_Arg;
-
- /* all the arguments (in a list) and a toggle for every possible option */
-
- typedef struct {
- Ptr_Cmd_Arg non_dash_arg_list;
- int dash_options[MAX_OPTIONS];
- } Cmd_Line, *Ptr_Cmd_Line;
-
- /*--------------------------------------------------------------------------*/
-
- extern char *malloc();
-
- extern int get_args();
-
- /* int argc; char **argv; Bool dup_error; Bool print_msg; */
- /* returns one of ARG_ERROR, NO_ARGS, or ARGS_PRESENT */
- /* if dup_error, then having two identical options on the command */
- /* line will cause an error. If print_msg, then any error that */
- /* is noticed is printed out to stderr. If !dup_error then */
- /* 'foo -a 3 4 -b -a 5' is equivalent to 'foo -a 3 4 5 -b' */
-
-
- extern Bool any_option_present();
-
- /* no arguments */
-
- extern Bool option_present();
-
- /* char achar; */
-
- extern char * option_arg();
-
- /* char achar; int n; */
-
- extern char * non_option_arg();
-
- /* int n; */
-
- extern int n_option_args();
-
- /* char achar; */
-
- extern int n_non_option_args();
-
- /* no arguments */
-
- extern int n_non_dash_args();
-
- /* no arguments */
-
- extern Bool check_option_args();
-
- /* char achar; int min; int max; */
-
- #define ALL_LEGAL 0
-
- extern char legal_options();
-
- /* char *legaloptions; */
- /* legaloptions should be a string of characters all in the range */
- /* a-zA-Z. Returns ALL_LEGAL if every option parsed in included */
- /* in the legaloptions string, otherwise returns the first option */
- /* character not in the string. */
-
- extern set_option();
-
- /* char achar */
-
- extern error_message();
-
- /* char *progname; char **argv; int index; char *usage; */
-
- extern print_args();
-
- /* debugging routine */
- SHAR_EOF
- if test 2401 -ne "`wc -c < 'toolsdir/args.h'`"
- then
- echo shar: error transmitting "'toolsdir/args.h'" '(should have been 2401 characters)'
- fi
- fi
- echo shar: extracting "'toolsdir/basics.h'" '(186 characters)'
- if test -f 'toolsdir/basics.h'
- then
- echo shar: will not over-write existing file "'toolsdir/basics.h'"
- else
- cat << \SHAR_EOF > 'toolsdir/basics.h'
- #define T 1
- #define F 0
-
- #define True 1
- #define False 0
-
- #define SUCCESS 1
- #define FAILURE 0
- #define ERROR -1
-
- #define Bool int
-
- #define MAXINT 2147483647
- #define MAXINTSTR "2147483647"
- SHAR_EOF
- if test 186 -ne "`wc -c < 'toolsdir/basics.h'`"
- then
- echo shar: error transmitting "'toolsdir/basics.h'" '(should have been 186 characters)'
- fi
- fi
- echo shar: extracting "'toolsdir/ctools.c'" '(20370 characters)'
- if test -f 'toolsdir/ctools.c'
- then
- echo shar: will not over-write existing file "'toolsdir/ctools.c'"
- else
- cat << \SHAR_EOF > 'toolsdir/ctools.c'
- /* -*- Mode: C; Package: (CTOOLS C) -*- */
-
- #include <ctype.h>
- #include <stdio.h>
-
- #ifdef BSD42
- #include <strings.h>
- #endif
-
- #include "ctools.h"
-
- /* miscellaneous fairly primitive routines that deal with characters, */
- /* strings, memory, simple input and pathnames. */
-
-
- /* Author: JP Massar */
- /* Thinking Machines Corporation */
-
- /* Included routines:
-
- emalloc
- anewstr
-
- copy
- fill
-
- to_upper_if_lower
- to_lower_if_upper
-
- buffconcat
- nbuffconcat
-
- slcompare
- slge_compare
- nocase_compare
-
- strfind
- strncfind
- strsearch
- strncsearch
-
- yes_or_no_check
-
- remove_excess_blanks
- ip_string_trim
- string_trim
- string_upcase
- string_downcase
-
- all_digits
- all_whitespace
- all_uppercase
- all_lowercase
- all_alphabetic
- all_alphanumeric
- all_ascii
-
- str_to_pos_int
-
- sreverse
- ip_sreverse
-
- temp_path
- perm_path
- make_path_numeric_extension
- make_path
- just_filename
-
- read_yes_or_no
- getline
- getlines
- ngetlines
- getfile
- ngetfile
- read_file_into_buffer
- efopen
-
- check_int
- check_string
-
- */
-
-
- extern char *malloc();
-
-
- char *emalloc (space) int space;
-
- /* allocate 'space' bytes, die if we have run out of memory. */
-
- {
- char *rval;
- if (space < 0) {
- fprintf(stderr,"Fatal error: argument to emalloc < 0\n");
- exit(-1);
- }
- if (0 == (rval = malloc((unsigned) space))) {
- fprintf(stderr,"Fatal error: No more memory\n");
- exit(-1);
- }
- return(rval);
- }
-
-
- char *anewstr (astring) char *astring;
-
- /* allocate space for and then copy a string. Returns pointer to */
- /* new string. */
-
- {
- char *newstr;
- newstr = emalloc(strlen(astring)+1);
- strcpy(newstr,astring);
- return(newstr);
- }
-
-
- copy (dest,src,n)
-
- /* copy n bytes */
-
- register char *dest,*src;
- register int n;
-
- { register int j = 0;
- while (j++ < n) *dest++ = *src++;
- }
-
-
- fill (addr,ch,n)
-
- /* fill n sequential bytes with 'ch' */
-
- register char *addr;
- register char ch;
- register int n;
-
- { register int j = 0;
- while (j++ < n) *addr++ = ch;
- }
-
-
- to_upper_if_lower (ch)
-
- char ch;
-
- { return(islower(ch) ? toupper(ch) : ch); }
-
-
- to_lower_if_upper (ch)
-
- char ch;
-
- { return(isupper(ch) ? tolower(ch) : ch); }
-
-
- buffconcat (buffer,s1,s2)
-
- /* concatenate two null terminated strings into a buffer. */
-
- char *buffer, *s1, *s2;
-
- { while (*s1 != '\0') *buffer++ = *s1++;
- while (*s2 != '\0') *buffer++ = *s2++;
- *buffer = '\0';
- }
-
-
- nbuffconcat (buffer,n,s1,s2,s3,s4,s5,s6)
-
- /* concatenates up to 6 strings into a buffer. Returns -1 if n */
- /* is not reasonable, otherwise returns 0. */
-
- char *buffer;
- int n;
- char *s1,*s2,*s3,*s4,*s5,*s6;
-
- {
- register char *b;
- register char *s;
- int i;
- b = buffer;
- if (n < 1 || n > 6) return(-1);
- for (i = 1; i <= 6; i++) {
- if (i > n) break;
- switch (i) {
- case 1 : s = s1; break;
- case 2 : s = s2; break;
- case 3 : s = s3; break;
- case 4 : s = s4; break;
- case 5 : s = s5; break;
- case 6 : s = s6; break;
- }
- while (*s != '\0') *b++ = *s++;
- }
- *b = '\0';
- return(0);
- }
-
-
- slcompare (s1,l1,s2,l2)
-
- /* compare strings with possible nulls in them given their lengths */
- /* only returns EQUAL (0) or NOT EQUAL (-1) */
-
- char *s1;
- int l1;
- char *s2;
- int l2;
-
- { int j;
- if (l1 != l2) return(-1);
- j = 0;
- while (j++ < l1)
- if (*s1++ != *s2++) return(-1);
- return(0);
- }
-
-
- slge_compare (s1,l1,s2,l2)
-
- /* returns -1 if s1 < s2; 1 if s2 < s1; 0 if s1 = s2 */
- /* ignores nulls in the strings */
-
- char *s1;
- int l1;
- char *s2;
- int l2;
-
- { int j,len;
- j = 0;
- len = l2 > l1 ? l1 : l2;
- while (j++ < len) {
- if (*s1 != *s2)
- return((*s1 < *s2) ? -1 : 1);
- s1++;
- s2++;
- }
- return((l2 == l1) ? 0 : ((l1 < l2) ? -1 : 1));
- }
-
- nocase_compare (s1,l1,s2,l2)
-
- /* treats nulls as normal characters. Returns same as slge_compare */
-
- char *s1;
- int l1;
- char *s2;
- int l2;
-
- { int j,len,ch1,ch2;
- j = 0;
- len = l2 > l1 ? l1 : l2;
- while (j++ < len) {
- ch1 = to_upper_if_lower(*s1++);
- ch2 = to_upper_if_lower(*s2++);
- if (ch1 != ch2) {
- return((ch1 < ch2) ? -1 : 1);
- }
- }
- return((l2 == l1) ? 0 : ((l1 < l2) ? -1 : 1));
- }
-
-
- char *strfind(s1,s2,fast)
-
- register char *s1;
- char *s2;
- Bool fast;
-
- {
- register int len1,len2;
- len2 = strlen(s2);
- if (fast) {
- while (*s1 != '\0')
- if (0 == strncmp(s1++,s2,len2)) return(s1-1);
- }
- else {
- len1 = strlen(s1);
- while (len1 >= len2) {
- if (0 == strncmp(s1++,s2,len2)) return(s1-1);
- len1--;
- }
- }
- return(0);
- }
-
-
- char *strncfind(s1,s2,fast)
-
- register char *s1;
- char *s2;
- Bool fast;
-
- {
- register int len1,len2;
- len2 = strlen(s2);
- if (fast) {
- while (*s1 != '\0')
- if (0 == nocase_compare(s1++,len2,s2,len2)) return(s1-1);
- }
- else {
- len1 = strlen(s1);
- while (len1 >= len2) {
- if (0 == nocase_compare(s1++,len2,s2,len2)) return(s1-1);
- len1--;
- }
- }
- return(0);
- }
-
-
- char *strsearch(s1,s1len,s2,s2len)
-
- /* do a substring search without noticing nulls */
- /* finds s2 in s1, returns pointer into s1 or 0 */
-
- register char *s1, *s2;
- register int s1len,s2len;
-
- { register char *pc;
- register char *bound;
- register char *pctemp;
- register char *s2temp;
- register int j;
-
- bound = s1 + s1len - s2len;
- for (pc = s1; pc <= bound; pc++) {
- pctemp = pc;
- s2temp = s2;
- for (j = 0; j < s2len; j++)
- if (*pctemp++ != *s2temp++) goto not_here;
- return(pc);
- not_here :
- continue;
- }
- return(0);
- }
-
-
- char *strncsearch(s1,s1len,s2,s2len)
-
- /* do a substring search without noticing nulls */
- /* finds s2 in s1, returns pointer into s1 or 0 */
- /* case independent */
-
- register char *s1, *s2;
- register int s1len,s2len;
-
- { register char *pc;
- register char *bound;
- register char *pctemp;
- register char *s2temp;
- register int j;
- char ch1, ch2;
-
- bound = s1 + s1len - s2len;
- for (pc = s1; pc <= bound; pc++) {
- pctemp = pc;
- s2temp = s2;
- for (j = 0; j < s2len; j++) {
- ch1 = *pctemp++;
- ch2 = *s2temp++;
- if (to_upper_if_lower(ch1) != to_upper_if_lower(ch2))
- goto not_here;
- }
- return(pc);
- not_here :
- continue;
- }
- return(0);
- }
-
-
- int remove_excess_blanks (newstring,oldstring)
-
- /* it is assumed that newstring is as long as oldstring if necessary */
-
- char *newstring,*oldstring;
-
- {
- int count = 0;
- int space_found = 0;
-
- /* skip over all blanks at beginning */
-
- if (*oldstring == ' ') {
- while (*oldstring == ' ') oldstring++;
- }
-
- while (*oldstring != '\0') {
- if (space_found && *oldstring == ' ') {
- oldstring++;
- continue;
- }
- space_found = (*oldstring == ' ');
- *newstring++ = *oldstring++;
- count++;
- }
-
- *newstring = '\0';
- if (count > 0 && *(newstring - 1) == ' ') {
- count--;
- *(newstring - 1) = '\0';
- }
-
- return(count);
-
- }
-
- int ip_string_trim (oldstring,trimchars,pretrim,posttrim)
-
- char *oldstring, *trimchars;
- Bool pretrim,posttrim;
-
- {
- Bool trim = T;
- char *np = oldstring, ch;
- int len;
-
- if (pretrim) {
- while (trim && ('\0' != (ch = *np))) {
- trim = (0 != index(trimchars,ch));
- if (trim) np++;
- }
- strcpy(oldstring,np);
- }
- if (1 >= (len = strlen(oldstring)) && pretrim) return(len);
- if (posttrim) {
- np = oldstring + len - 1;
- while (T) {
- ch = *np;
- trim = (0 != index(trimchars,ch));
- if (trim) *np == '\0';
- if (!trim || np == oldstring) break;
- np--;
- }
- }
- return(strlen(oldstring));
- }
-
- int string_trim (newstring,oldstring,trimchars,pretrim,posttrim)
-
- char *newstring, *oldstring, *trimchars;
- Bool pretrim, posttrim;
-
- {
- strcpy(newstring,oldstring);
- return(ip_string_trim(newstring,trimchars,pretrim,posttrim));
- }
-
- char *string_upcase (astring) char *astring;
- {
- while (*astring) {
- *astring = to_upper_if_lower(*astring);
- astring++;
- }
- }
-
- char *string_downcase (astring) char *astring;
- {
- while (*astring) {
- *astring = to_lower_if_upper(*astring);
- astring++;
- }
- }
-
-
- yes_or_no_check (astring) char *astring;
-
- /* returns 1 if yes, 0 if no, -1 if neither */
- /* works for 'Y' 'YES' 'NO' 'N' in any capitalization */
-
- {
- int len;
- len = strlen(astring);
- if (len == 0 || len > 3) return(-1);
- if (0 == nocase_compare(astring,len,"YES",3) ||
- 0 == nocase_compare(astring,len,"Y",1))
- return(1);
- if (0 == nocase_compare(astring,len,"NO",2) ||
- 0 == nocase_compare(astring,len,"N",1))
- return(0);
- return(-1);
- }
-
-
- Bool all_digits (astring) char *astring;
-
- /* test whether every character is a digit (0-9) */
-
- {
- while (*astring != '\0')
- if (!isdigit(*astring++)) return(F);
- return(T);
- }
-
-
- Bool all_whitespace (astring) char *astring;
-
- /* test whether every character is a blank or a tab */
-
- {
- register char ch;
- while ((ch = *astring++) != '\0') {
- if (ch == ' ' || ch == '\t') continue;
- return(F);
- }
- return(T);
- }
-
- Bool all_uppercase(astring) char *astring;
- {
- register char ch;
- while ((ch = *astring++) != '\0') {
- if (!isupper(ch)) return(F);
- }
- return(T);
- }
-
- Bool all_lowercase(astring) char *astring;
- {
- register char ch;
- while ((ch = *astring++) != '\0') {
- if (!islower(ch)) return(F);
- }
- return(T);
- }
-
- Bool all_alphabetic(astring) char *astring;
- {
- register char ch;
- while ((ch = *astring++) != '\0') {
- if (!isalpha(ch)) return(F);
- }
- return(T);
- }
-
- Bool all_ascii(astring) char *astring;
- {
- register char ch;
- while ((ch = *astring++) != '\0') {
- if (!isascii(ch)) return(F);
- }
- return(T);
- }
-
- Bool all_alphanumeric(astring) char *astring;
- {
- register char ch;
- while ((ch = *astring++) != '\0') {
- if (!isalnum(ch)) return(F);
- }
- return(T);
- }
-
- int str_to_pos_int (astring,low,high) char *astring; int low,high;
-
- /* returns -1 if *astring is not composed of digits. */
- /* returns -2 if the integer is out of range. */
- /* treats all digit strings as decimal. */
-
- {
- int value,len,maxlen,j;
- maxlen = strlen(MAXINTSTR);
- len = strlen(astring);
- if (!all_digits(astring)) return(-1);
- if (len > maxlen) return(-2);
- if (len == maxlen) {
- if (1 == strcmp(astring,MAXINTSTR)) return(-2);
- }
- for (j = 0; j < len-1; j++) {
- if (*astring != '0') break;
- astring++;
- }
- sscanf(astring,"%d",&value);
- if (value < low || value > high) return(-2);
- return(value);
- }
-
-
- int sreverse (buffer,astring) char *buffer, *astring;
- {
- register int last = strlen(astring);
- buffer[last--] = '\0';
- while (last >= 0) buffer[last--] = *astring++;
- }
-
- char * ip_sreverse (astring) char *astring;
- {
- register int last = strlen(astring) - 1;
- register int first = 0;
- register char ch;
- while (first < last) {
- ch = astring[first];
- astring[first++] = astring[last];
- astring[last--] = ch;
- }
- return(astring);
- }
-
-
-
- static char pathbuffer[PATH_MAXPATHLEN];
-
-
- char *temp_path (dir,filename) char *dir; char *filename;
-
- {
- return(make_path(dir,filename,"",F));
- }
-
-
- char *perm_path (dir,filename) char *dir; char *filename;
-
- {
- return(make_path(dir,filename,"",T));
- }
-
-
- char *make_path_numeric_extension (dir,filename,extension,perm)
-
- char *dir, *filename;
- int extension;
- Bool perm;
-
- {
- char buffer[20];
- sprintf(buffer,"%d",extension);
- return(make_path(dir,filename,buffer,perm));
- }
-
-
- char *make_path (dir,filename,extension,perm)
-
- char *dir, *filename, *extension;
- Bool perm;
-
- {
- char *rval;
- if (!perm && (strlen(dir) + 1 + strlen(filename) + strlen(extension) + 1 >=
- PATH_MAXPATHLEN)) {
- return((char *) 0);
- }
- nbuffconcat(pathbuffer,4,dir,"/",filename,extension);
- if (!perm) return(pathbuffer);
- rval = emalloc(strlen(pathbuffer) + 1);
- strcpy(rval,pathbuffer);
- return(rval);
- }
-
-
- char *just_filename (path,new,perm) char *path; Bool new,perm;
-
- {
- char *fnp,*rval;
- fnp = (0 == (fnp = rindex(path,'/'))) ? path : fnp + 1;
- if (!new) return(fnp);
- if (!perm) {
- strcpy(pathbuffer,fnp);
- return(pathbuffer);
- }
- else {
- rval = emalloc(strlen(fnp) + 1);
- strcpy(rval,fnp);
- return(rval);
- }
- }
-
-
-
- read_yes_or_no (iport,oport,prompt,helpstring,quitstring)
-
- /* prints prompt, then reads from port until it gets 'Y', 'N', 'YES' or */
- /* 'NO' (case independently). If helpstring and/or quitstring are not */
- /* "" or (char *) 0 then if the user types in one of those ANSWER_HELP */
- /* or ANSWER_QUIT are returned, otherwise ANSWER_NO or ANSWER_YES are */
- /* eventually returned. */
-
- FILE *iport, *oport;
- char *prompt, *helpstring, *quitstring;
-
- {
- char buffer[20],buffer2[20];
- int bl,hl,ql,len;
-
- buffer[19] = '\0';
-
- while (T) {
-
- fprintf(oport,"%s",prompt);
- switch (len = getline(iport,buffer,20)) {
- case (AT_EOF) :
- return(ANSWER_EOF);
- break;
- case (TOO_MANY_CHARS) :
- break;
- default :
- if (0 == (bl = remove_excess_blanks(buffer2,buffer))) break;
- switch (yes_or_no_check(buffer2)) {
- case (0) :
- return(ANSWER_NO);
- case (1) :
- return(ANSWER_YES);
- case (-1) :
- if (helpstring != (char *) 0 && (hl = strlen(helpstring)) > 0) {
- if (0 == nocase_compare(buffer2,bl,helpstring,hl)) {
- return(ANSWER_HELP);
- }
- }
- if (quitstring != (char *) 0 && (ql = strlen(quitstring)) > 0) {
- if (0 == nocase_compare(buffer2,bl,quitstring,ql)) {
- return(ANSWER_QUIT);
- }
- }
- break;
- }
- break;
- }
-
- fprintf(oport,"Please answer 'YES' or 'NO'\n");
- continue;
-
- }
-
- }
-
-
- int getline (iport,buffer,buflen) FILE *iport; char *buffer; int buflen;
-
- /* reads a line into buffer. Does not put the '\n' into buffer. */
- /* Returns AT_EOF if at end of file when called. If it encounters */
- /* end of file after reading at least one character, the eof is treated */
- /* as if it were a newline. Returns TOO_MANY_CHARS if more than */
- /* buflen - 1 characters are read before encountering a newline. */
- /* In this case exactly buflen - 1 characters are read. */
- /* The last character read is always follwed by a '\0'. */
- /* if successful getline returns the number of characters read exclusive */
- /* of a terminating newline or eof. */
-
- {
- int ch;
- char *bptr = buffer;
- int nchars = 0;
-
- if (buflen <= 0) return(TOO_MANY_CHARS);
-
- while (T) {
- switch (ch = getc(iport)) {
- case (EOF) :
- case ('\n') :
- if (ch == EOF && nchars == 0) return(AT_EOF);
- *bptr = '\0';
- return(nchars);
- default :
- if (++nchars == buflen) {
- *bptr = '\0';
- ungetc(ch,iport);
- return(TOO_MANY_CHARS);
- }
- *bptr++ = ch;
- }
-
- }
-
- }
-
-
- int getlines (fp,n,ptr_lines,linebuf,maxlinelen)
-
- /* See documentation for getfile below */
-
- FILE *fp;
- int n;
- char ***ptr_lines;
- char *linebuf;
- int maxlinelen;
-
- {
- int len;
- char *line;
- if (0 > (len = getline(fp,linebuf,maxlinelen))) {
- if (len == AT_EOF) {
- *ptr_lines = (char **) emalloc(n * sizeof(char **));
- return(n);
- }
- else {
- return(TOO_MANY_CHARS);
- }
- }
- else {
- line = emalloc(len+1);
- strcpy(line,linebuf);
- len = getlines(fp,n+1,ptr_lines,linebuf,maxlinelen);
- if (len == TOO_MANY_CHARS) return(TOO_MANY_CHARS);
- (*ptr_lines)[n] = line;
- return(len);
- }
- }
-
-
- int getfile (filename,ptr_lines,linebuf,maxlinelen)
-
- /* read in a file as an array of character strings */
- /* 'maxlinelen+1' is the maximum length a line of the file is allowed */
- /* to be. 'linebuf' must be at least 'maxlinelen+1' characters long. */
- /* Returns the number of lines in the file (and therefore the number */
- /* of entries in *ptr_lines) if successful. Returns IOERROR if it */
- /* could not open the file to read from. Returns TOO_MANY_CHARS if */
- /* it encounters a line longer than 'maxlinelen' characters. */
-
- /* Space for each line is malloc'ed as it is read in and the text for */
- /* the jth line is stored in (*ptr_lines)[j] */
-
- char *filename;
- char ***ptr_lines;
- char *linebuf;
- int maxlinelen;
-
- {
- FILE *fp;
- int nlines;
- if (NULL == (fp = fopen(filename,"r"))) return(IOERROR);
- nlines = getlines(fp,0,ptr_lines,linebuf,maxlinelen);
- fclose(fp);
- return(nlines);
- }
-
-
- int ngetlines (fp,n,ptr_lines,linebuf,maxlinelen)
-
- /* See documentation for ngetfile below */
-
- FILE *fp;
- int n;
- char ***ptr_lines;
- char *linebuf;
- int maxlinelen;
-
- {
- int len;
- int nlines = 0;
- *ptr_lines = (char **) emalloc(n * sizeof(char **));
- while (T) {
- if (0 > (len = getline(fp,linebuf,maxlinelen))) {
- if (len == AT_EOF) {
- return(nlines);
- }
- else {
- return(TOO_MANY_CHARS);
- }
- }
- else {
- if (++nlines > n) {
- return(TOO_MANY_LINES);
- }
- (*ptr_lines)[nlines-1] = anewstr(linebuf);
- }
- }
- }
-
-
-
- int ngetfile (n,filename,ptr_lines,linebuf,maxlinelen)
-
- /* Same as getfile except that at most n lines will be read. */
- /* If it attempts to read more than n lines, TOO_MANY_LINES will */
- /* be returned. */
-
- int n;
- char *filename;
- char ***ptr_lines;
- char *linebuf;
- int maxlinelen;
-
- {
- FILE *fp;
- int nlines;
- if (NULL == (fp = fopen(filename,"r"))) return(IOERROR);
- nlines = ngetlines(fp,n,ptr_lines,linebuf,maxlinelen);
- fclose(fp);
- return(nlines);
- }
-
-
- extern int read_file_into_buffer (
-
- filename,ptr_lines,maxlines,buffer,buflen,linebuffer,linebuflen
-
- )
-
- char *filename;
- char ***ptr_lines;
- int maxlines;
- char *buffer;
- int buflen;
- char *linebuffer;
- int linebuflen;
-
- /* *ptr_lines should be an array of character string pointers maxlines */
- /* big. buffer should be an array of characters buflen long. The routine */
- /* reads lines using getline and stores them into buffer, terminating each */
- /* with a null. A pointer to the nth line read is stored in *ptr_lines[n] */
- /* Returns IOERROR if it cannot open the file for reading, TOO_MANY_LINES */
- /* if more than maxlines were read in, TOO_MANY_CHARS if buffer is */
- /* filled before end of file is reached, and LINE_TOO_LONG is any line is */
- /* longer than linebuflen. Returns number of lines read in if successful. */
-
- {
- FILE *fp;
- int linecount,charcount,len;
- char *bp;
- char **lines;
-
- if (NULL == (fp = fopen(filename,"r"))) return(IOERROR);
- linecount = 0;
- charcount = 0;
- bp = buffer;
- lines = *ptr_lines;
-
- while (T) {
-
- if (0 > (len = getline(fp,linebuffer,linebuflen))) {
- fclose(fp);
- if (len == AT_EOF) {
- return(linecount);
- }
- else {
- return(LINE_TOO_LONG);
- }
- }
-
- if (linecount >= maxlines) {
- fclose(fp);
- return(TOO_MANY_LINES);
- }
-
- charcount += len;
- if (charcount >= buflen) {
- fclose(fp);
- return(TOO_MANY_CHARS);
- }
-
- strcpy(bp,linebuffer);
- lines[linecount++] = bp;
- bp += (len + 1);
-
- }
-
- }
-
- extern char *efopen (filename,mode) char *filename; char *mode;
-
- /* The routine simply calls fopen with the same arguments, but prints a */
- /* reasonable error message and calls exit if the call to fopen fails. */
-
- {
- FILE *fp;
- if (NULL == (fp = fopen(filename,mode))) {
- fprintf(stderr,"Could not open %s, mode: %s\n",filename,mode);
- perror("Reason: ");
- exit(1);
- }
- return((char *) fp);
- }
-
-
-
- extern int record_fseek (fp,rnum,fromwhere,rsize,hdrsize)
-
- FILE *fp;
- long rnum;
- int fromwhere;
- int rsize;
- int hdrsize;
-
- {
- if (fromwhere == 0) {
- return(fseek(fp,(long) ((rnum - 1)*rsize + hdrsize),0));
- }
- else {
- return(fseek(fp,(long) (rnum*rsize),fromwhere));
- }
- }
-
-
- Bool check_string (s,minlen,maxlen) char *s; long minlen,maxlen;
- {
- long len;
- if (s == 0) return(F);
- len = strlen(s);
- return (len >= minlen && len <= maxlen);
- }
-
- SHAR_EOF
- if test 20370 -ne "`wc -c < 'toolsdir/ctools.c'`"
- then
- echo shar: error transmitting "'toolsdir/ctools.c'" '(should have been 20370 characters)'
- fi
- fi
- echo shar: extracting "'toolsdir/ctools.h'" '(11301 characters)'
- if test -f 'toolsdir/ctools.h'
- then
- echo shar: will not over-write existing file "'toolsdir/ctools.h'"
- else
- cat << \SHAR_EOF > 'toolsdir/ctools.h'
- /* -*- Mode: C; Package: (CTOOLS C) -*- */
-
- #ifndef Bool
- #define Bool int
- #endif
-
- #ifndef T
- #define T 1
- #endif
-
- #ifndef F
- #define F 0
- #endif
-
- #ifndef MAXINT
- #define MAXINT 2147483647
- #define MAXINTSTR "2147483647"
- #endif
-
- #ifndef MAXPATHLEN
- #define MAXPATHLEN 80
- #endif
-
- extern char *emalloc();
-
- /* int space; */
- /* space must be greater than 0 */
- /* Causes executution to halt with a 'Fatal error' message if memory */
- /* cannot be allocated, otherwise returns pointer to malloc-ed space */
-
- extern char *anewstr();
-
- /* char *astring; */
- /* emalloc's space and copies astring into that space. Returns pointer */
- /* to new string. */
-
-
- extern int copy();
-
- /* char *dest, *src; int n; */
- /* copies exactly n bytes. */
- /* return value undefined. Use only as procedure. */
-
- extern int fill();
-
- /* char *addr, ch; int n; */
- /* copies ch into n consecutive bytes. */
- /* return value undefined. Use only as procedure. */
-
- extern int to_upper_if_lower();
-
- /* char ch; Returns possibly upper-cased value. */
-
- extern int to_lower_if_upper();
-
- /* char ch; Returns possibly lower-cased value. */
-
- extern int buffconcat();
-
- /* char *buffer, *s1, *s2; */
- /* s1 and s2 must be null terminated. Buffer must be at least */
- /* strlen(s1) + strlen(s2) + 1 characters long. Buffer is null */
- /* terminated upon completion. */
-
- /* return value undefined. Use only as procedure. */
-
- extern int nbuffconcat();
-
- /* char *buffer; int n; char *s1,*s2,*s3,*s4,*s5,*s6; */
- /* all the strings must be null terminated. Buffer must be big enough */
- /* to hold the null terminated result. 0 < n < 7 ..
- /* returns -1 if n is out of range, otherwise 0 */
-
- extern int slcompare();
-
- /* char *s1; int l1; char *s2; int l2 */
- /* does not stop if it encounters a null character. */
- /* returns 0 if equal, -1 if not equal */
-
- extern int slge_compare();
-
- /* char *s1; int l1; char *s2; int l2 */
- /* does not stop if it encounters a null character. */
- /* returns 0 if equal, -1 if s1 < s2, 1 if s1 > s2 */
-
- extern int nocase_compare();
-
- /* char *s1; int l1; char *s2; int l2 */
- /* does not stop if it encounters a null character. */
- /* returns 0 if equal, -1 if s1 < s2, 1 if s1 > s2 case independently. */
-
- extern char * strfind();
-
- /* char *s1; char *s2; int fast; */
- /* finds s2 as a substring of s1. s1 and s2 are null terminated. */
- /* returns 0 if not found, otherwise pointer into s1 to first matching */
- /* character. */
-
- /* WARNING: will access off the end of s1 in the interest of efficiency */
- /* if 'fast' is non-zero. */
-
- extern char * strncfind();
-
- /* char *s1; char *s2; int fast; */
- /* finds s2 as a substring of s1 case independently. s1 and s2 are */
- /* null terminated. */
- /* returns 0 if not found, otherwise pointer into s1 to first matching */
- /* character. */
-
- /* WARNING: will access off the end of s1 in the interest of efficiency */
- /* if 'fast' is non-zero. */
-
- extern char * strsearch();
-
- /* char *s1; int l1; char *s2; int l2 */
- /* finds s2 as a substring of s1. Does not stop if it encounters a null. */
- /* returns pointer into s1, otherwise (char *) 0 if search fails */
- /* case dependent */
-
- extern char * strncsearch();
-
- /* char *s1; int l1; char *s2; int l2 */
- /* finds s2 as a substring of s1. */
- /* returns pointer into s1, otherwise (char *) 0 if search fails */
- /* case independent */
-
- extern int remove_excess_blanks();
-
- /* char *newstring, *oldstring; */
- /* newstring must be long enough to hold the result, which may be as */
- /* long as oldstring. oldstring must be null terminated. */
- /* an excess blank is any blank before the first non-blank character, */
- /* any blank after the last non-blank character, and any blank immediately */
- /* following a blank. */
- /* returns length of newstring */
-
- extern int yes_or_no_check();
-
- /* char *astring; */
- /* returns 1 for yes, 0 for no, -1 for neither. */
- /* astring must be one of "YES", "Y", "NO", "N" in any capitalization. */
-
-
- /* These routines return T if every char satisfies a certain condition. */
- /* These returns all returns T if given a null string. */
-
- extern Bool all_digits();
- extern Bool all_whitespace();
- extern Bool all_uppercase();
- extern Bool all_lowercase();
- extern Bool all_alphabetic();
- extern Bool all_alphanumeric();
- extern Bool all_ascii();
-
-
- extern int str_to_pos_int();
-
- /* char *astring; int low,high; */
- /* low must be >= 0. */
- /* returns -1 if *astring is not composed of digits. */
- /* returns -2 if the integer is out of range. */
- /* despite its name, 0 can be returned as a legitimate value. */
- /* treats all digit strings as decimal. */
-
-
- extern int sreverse();
-
- /* char *buffer; char *astring; */
- /* puts the characters of astring in reverse order into buffer. */
- /* buffer must be at least as long as astring + 1. */
- /* buffer is null terminated when done. */
- /* No return value. Use only as procedure. */
-
- extern char *ip_sreverse();
-
- /* char *astring; */
- /* Returns astring with its characters reversed. */
- /* reversal is done in place. */
-
-
-
- #define PATH_MAXPATHLEN 256
-
- char *temp_path();
-
- /*
- char *dir; char *filename;
-
- Returns a pointer to a character string containing the string
- <dir>/<filename>. The pointer points to a buffer which will may get
- overwritten if any functions in this package are subsequently called.
- 0 is returned if the pathname would exceed PATH_MAXPATHLEN-1 chars.
- */
-
-
- char *perm_path();
-
- /*
- char *dir; char *filename;
-
- Same as temp_path, except the pathname string is malloc'ed and is thus
- permanent unless specifically freed by the user. Further, no limit
- on the size of the path is made.
- */
-
-
- char *make_path();
-
- /*
- char *dir; char *filename; char *extension; Bool perm;
-
- Creates <dir>/<filename><extension> . The string returned is permanent
- or not depending on 'perm'. If perm is not true, 0 will be returned if
- the resulting path exceeds PATH_MAXPATHLEN-1 chars.
- */
-
-
- char *make_path_numeric_extension();
-
- /*
- char *dir; char *filename; int extension; Bool perm;
-
- Same as make_path except that extension is first converted into a
- string using sprintf.
- */
-
-
- char *just_filename();
-
- /*
- char *path; Bool new; Bool perm;
-
- Given a path of the form /<x>/<y>/<z> returns <z>. If new is not set
- then a pointer into the original input string is returned. If new is
- set a copy is returned, either permanent or not depending on perm.
- */
-
-
- #define ANSWER_NO 0
- #define ANSWER_YES 1
- #define ANSWER_HELP 2
- #define ANSWER_QUIT 3
- #define ANSWER_EOF 4
-
- #define AT_EOF -1
- #define TOO_MANY_CHARS -2
- #define IOERROR -3
- #define TOO_MANY_LINES -4
- #define LINE_TOO_LONG -5
-
- extern read_yes_or_no ();
-
- /* FILE *iport, *oport; char *prompt; char *helpstring; char *quitstring; */
-
- /* prints prompt, then reads from iport until is gets 'Y', 'N', 'YES' or */
- /* 'NO' (case independently). If helpstring and/or quitstring are not */
- /* "" or (char *) 0 then if the user types in one of those ANSWER_HELP */
- /* or ANSWER_QUIT are returned, otherwise ANSWER_NO or ANSWER_YES are */
- /* eventually returned. */
-
-
- extern int getline ();
-
- /* FILE *iport; char *buffer; int buflen; */
-
- /* reads a line into buffer. Does not put the '\n' into buffer. */
- /* Returns AT_EOF if at end of file when called. If it encounters */
- /* end of file after reading at least one character, the eof is treated */
- /* as if it were a newline. Returns TOO_MANY_CHARS if more than */
- /* buflen - 1 characters are read before encountering a newline. */
- /* In this case exactly buflen - 1 characters are read. */
- /* The last character read is always follwed by a '\0'. */
- /* if successful getline returns the number of characters read exclusive */
- /* of a terminating newline or eof. */
-
-
- extern int getlines();
-
- /* FILE *fp; int n; char ***ptr_lines; char *linebuf; int maxlinelen; */
- /* See documentation for getfile below */
- /* If called, 'n' must have a value 0. */
-
- extern int getfile();
-
- /* char *filename; char ***ptr_lines; char *linebuf; int maxlinelen; */
-
- /* read in a file as an array of character strings */
- /* 'maxlinelen+1' is the maximum length a line of the file is allowed */
- /* to be. 'linebuf' must be at least 'maxlinelen+1' characters long. */
- /* Returns the number of lines in the file (and therefore the number */
- /* of entries in *ptr_lines) if successful. Returns IOERROR if it */
- /* could not open the file to read from. Returns TOO_MANY_CHARS if */
- /* it encounters a line longer than 'maxlinelen' characters.
-
- /* Space for each line is malloc'ed as it is read in and the text for */
- /* the jth line is stored in (*ptr_lines)[j] */
-
- /* Only works for fairly small files as it recurses its way through the */
- /* file and does a lot of malloc-ing. Use read_file_into_buffer or */
- /* ngetfile for large files. */
-
- extern int ngetlines();
-
- /* FILE *fp; int n; char ***ptr_lines; char *linebuf; int maxlinelen; */
- /* Same as getlines, except at most 'n' lines will be read. Returns */
- /* TOO_MANY_LINES if more than 'n' lines are present. */
-
- extern int ngetfile();
-
- /* int n; char *filename; char ***ptr_lines; char *linebuf; int maxlinelen; */
- /* See ngetlines above. */
-
- extern int read_file_into_buffer();
-
- /* char *filename;
- char ***ptr_lines;
- int maxlines;
- char *buffer;
- int buflen;
- char *linebuffer;
- int linebuflen;
- */
-
- /* *ptr_lines should be an array of character string pointers maxlines */
- /* big. buffer should be an array of characters buflen long. The routine */
- /* reads lines using getline and stores them into buffer, terminating each */
- /* with a null. A pointer to the nth line read is stored in *ptr_lines[n] */
- /* Returns IOERROR if it cannot open the file for reading, TOO_MANY_LINES */
- /* if more than maxlines were read in, TOO_MANY_CHARS if buffer is */
- /* filled before end of file is reached, and LINE_TOO_LONG is any line is */
- /* longer than linebuflen. Returns number of lines read in if successful. */
-
- extern char *efopen();
-
- /* char *filename; char *mode */
-
- /* Actually returns a (FILE *), so one must cast the return value to this */
- /* type. It doesn't return a (FILE *) explicitly because then to include */
- /* this file one would have to include <stdio.h> explicitly before it. */
- /* The routine simply calls fopen with the same arguments, but prints a */
- /* reasonable error message and calls exit if the call to fopen fails. */
-
-
- extern int record_fseek();
-
- /* FILE *fp; long rnum; int fromwhere; int rsize; int hdrsize; */
-
- /* Assumes a file is divided into fixed length records with a fixed length */
- /* header (possibly 0 bytes). Performs a fseek which moves to the start */
- /* of a given record. Record numbers begin with 1. */
-
- /* Returns what fseek returns. */
-
- /* 'rnum' is either relative or absolute, depending on 'fromwhere' which */
- /* corresponds to the 'ptrname' argument of fseek. */
-
-
- Bool check_string();
-
- /* char *str; long minlen; long maxlen; */
-
- /* Returns T if str is not 0 and has a length between minlen and maxlen */
- /* inclusived, otherwise returns F. */
-
-
- #ifndef check_int
- #define check_int(i,minval,maxval) ((i) >= (minval) && (i) <= (maxval))
- #endif
- SHAR_EOF
- if test 11301 -ne "`wc -c < 'toolsdir/ctools.h'`"
- then
- echo shar: error transmitting "'toolsdir/ctools.h'" '(should have been 11301 characters)'
- fi
- fi
- echo shar: extracting "'toolsdir/mem.c'" '(2157 characters)'
- if test -f 'toolsdir/mem.c'
- then
- echo shar: will not over-write existing file "'toolsdir/mem.c'"
- else
- cat << \SHAR_EOF > 'toolsdir/mem.c'
- /**************************************************************************/
- /**************************************************************************/
-
-
- /***** Block Memory Allocator *****/
-
-
- /**************************************************************************/
- /**************************************************************************/
-
- /* Author: JP Massar */
-
- #include <stdio.h>
-
- #include "sys5.h"
-
- #ifdef BSD42
- #include <strings.h>
- #endif
-
- #define NO_MORE_MEMORY -1
-
- static int bytes_left; /* space left in current block */
- static char *ptr_next_byte; /* next free byte */
- static char *ptr_space; /* current block */
- static int chunk_size; /* size of block last allocated */
-
- extern char *malloc();
-
-
- int allocate_memory_chunk (space) int space;
-
- /* malloc up a new block of memory. Set our static variables */
- /* returns NO_MORE_MEMORY if can't allocate block. */
-
- {
- if (0 == (ptr_space = malloc(space))) {
- fprintf(stderr,"fatal error, no more memory\n");
- return(NO_MORE_MEMORY);
- }
- ptr_next_byte = ptr_space;
- bytes_left = space;
- chunk_size = space;
- return(0);
- }
-
-
- char * get_memory_chunk (size) int size;
-
- /* allocate a small segment out of our large block of memory. If we */
- /* run out allocate another block. Adjust our static variables. */
- /* returns 0 if no more memory. */
-
- { char *rval;
-
- if (size > chunk_size) {
- fprintf(stderr,"attempt to allocate too large a chunk\n");
- return(0);
- }
-
- if (size > bytes_left) {
- if (NO_MORE_MEMORY == allocate_memory_chunk(chunk_size)) {
- return(0);
- }
- return(get_memory_chunk(size));
- }
-
- rval = ptr_next_byte;
- ptr_next_byte += size;
- bytes_left -= size;
- return(rval);
-
- }
-
-
- char * store_string (str,len) char *str; int len;
-
- /* put copy of a string into storage in a memory block. Return a pointer to */
- /* the copied string. Returns 0 if out of memory. */
-
- { char *ptr_space;
-
- if (0 == (ptr_space = get_memory_chunk(len+1))) {
- return(0);
- }
- strcpy(ptr_space,str);
- return(ptr_space);
- }
- SHAR_EOF
- if test 2157 -ne "`wc -c < 'toolsdir/mem.c'`"
- then
- echo shar: error transmitting "'toolsdir/mem.c'" '(should have been 2157 characters)'
- fi
- fi
- echo shar: extracting "'toolsdir/mem.h'" '(209 characters)'
- if test -f 'toolsdir/mem.h'
- then
- echo shar: will not over-write existing file "'toolsdir/mem.h'"
- else
- cat << \SHAR_EOF > 'toolsdir/mem.h'
- extern int allocate_memory_chunk(); /* arg1: int space */
-
- extern char * get_memory_chunk(); /* arg1: int size */
-
- extern char * store_string(); /* arg1: char *str, arg2: int len */
- SHAR_EOF
- if test 209 -ne "`wc -c < 'toolsdir/mem.h'`"
- then
- echo shar: error transmitting "'toolsdir/mem.h'" '(should have been 209 characters)'
- fi
- fi
- echo shar: extracting "'toolsdir/menu.c'" '(7644 characters)'
- if test -f 'toolsdir/menu.c'
- then
- echo shar: will not over-write existing file "'toolsdir/menu.c'"
- else
- cat << \SHAR_EOF > 'toolsdir/menu.c'
- #include <stdio.h>
- #include <varargs.h>
- #include "ctools.h"
- #include "menu.h"
- #include "sys5.h"
-
-
- static char line[MAX_MENU_RESPONSE_LENGTH];
-
-
- menu_match (
-
- ptr_rval,ptr_ur,prompt,casetest,isub,r_no_match,r_ambiguous,n_options,
- va_alist
-
- )
-
- int *ptr_rval;
- char **ptr_ur;
- char *prompt;
- int casetest;
- int isub;
- int r_no_match;
- int r_ambiguous;
- int n_options;
- va_dcl
-
- {
-
- char sline[MAX_MENU_RESPONSE_LENGTH];
- char *option, *options[MAX_MENU_OPTIONS];
- int rvals[MAX_MENU_OPTIONS];
- int j,found,*addr,len,optionlen,rval,compare,blankindex;
- va_list pvar;
-
- if (n_options > MAX_MENU_OPTIONS) return(MENU_ERROR);
- for (j = 0; j < MAX_MENU_RESPONSE_LENGTH; j++) line[j] = ' ';
-
- /* grab all the menu options and return values. */
-
- blankindex = -1;
- va_start(pvar);
- for (j = 0; j < n_options; j++) {
- options[j] = va_arg(pvar,char *);
- if (0 == strlen(options[j])) {
- if (blankindex == -1) blankindex = j;
- }
- rvals[j] = va_arg(pvar,int);
- }
- va_end(pvar);
-
- try_again :
-
- /* get the user's response */
-
- printf("%s",prompt);
- switch (rval = getline(stdin,line,MAX_MENU_RESPONSE_LENGTH)) {
- case AT_EOF :
- return(MENU_EOF);
- break;
- case TOO_MANY_CHARS :
- fprintf(stderr,"Response is too long to handle. Please try again\n");
- goto try_again;
- break;
- default :
- *ptr_ur = line;
- remove_excess_blanks(sline,line);
- len = strlen(sline);
- break;
- }
-
- found = 0;
- rval = MENU_NO_MATCH;
-
- if (all_whitespace(sline)) {
- if (blankindex == -1) goto try_again;
- rval = MENU_MATCH;
- *ptr_rval = rvals[blankindex];
- goto rtn;
- }
-
- for (j = 0; j < n_options; j ++) {
-
- /* if what he typed in is longer than any option it can't match */
-
- optionlen = strlen(options[j]);
- if (len > optionlen) continue;
-
- /* if we aren't matching initial substrings, the response must */
- /* match exactly. */
-
- if (!isub && len != optionlen) continue;
-
- /* use different comparision functions depending on whether case */
- /* is important or not. */
-
- compare = casetest ?
- strncmp(sline,options[j],len) :
- nocase_compare(sline,len,options[j],len);
-
- /* if we must match exactly, if we find a match exit immediately. */
- /* if we can match on an initial substring, if we've already found */
- /* a match then we have an ambiguity, otherwise note that we've */
- /* matched and continue looking in case of ambiguities */
-
- if (0 == compare) {
- if (!isub) {
- found = 1;
- *ptr_rval = rvals[j];
- rval = MENU_MATCH;
- break;
- }
- if (found && isub) {
- rval = MENU_AMBIGUOUS;
- break;
- }
- else {
- found = 1;
- *ptr_rval = rvals[j];
- rval = MENU_MATCH;
- }
- }
- else {
- continue;
- }
- }
-
- rtn :
-
- switch (rval) {
- case MENU_MATCH :
- break;
- case MENU_NO_MATCH :
- if (r_no_match) {
- printf("Your response does not match any option. Try again\n");
- goto try_again;
- }
- break;
- case MENU_AMBIGUOUS :
- if (r_ambiguous) {
- printf("Your response is ambiguous. Try again\n");
- goto try_again;
- }
- break;
- default :
- fprintf(stderr,"Impossible case value in menu_match\n");
- exit(-1);
- }
-
- return(rval);
-
- }
-
-
- menu_yes_no (prompt,allow_help) char *prompt; int allow_help;
-
- {
- int menuval,rval;
- char *response;
-
- redo :
-
- if (!allow_help) {
- rval = menu_match (
- &menuval,&response,
- prompt,
- 0,1,0,0,2,
- "Yes",MENU_YES,
- "No",MENU_NO
- );
- }
- else {
- rval = menu_match (
- &menuval,&response,
- prompt,
- 0,1,0,0,4,
- "Yes",MENU_YES,
- "No",MENU_NO,
- "?",MENU_HELP,
- "Help",MENU_HELP
- );
- }
- switch (rval) {
- case MENU_MATCH :
- return(menuval);
- break;
- case MENU_NO_MATCH :
- fprintf(stderr,"Please type 'Yes' or 'No'...\n");
- goto redo;
- break;
- case MENU_EOF :
- return(MENU_EOF);
- break;
- default :
- fprintf(stderr,"Fatal error: Impossible return in menu_yes_no\n");
- exit(-1);
- }
- }
-
-
- extern int menu_data_help_or_abort (prompt,abortstring,ptr_response)
-
- char *prompt, *abortstring, **ptr_response;
-
- {
- int rval,menuval;
- rval = menu_match (
- &menuval,ptr_response,
- prompt,
- 0,1,0,1,3,
- abortstring,MENU_ABORT,
- "?",MENU_HELP,
- "Help",MENU_HELP
- );
- switch (rval) {
- case MENU_NO_MATCH :
- return(MENU_DATA);
- break;
- case MENU_MATCH :
- return(menuval);
- break;
- case MENU_EOF :
- return(MENU_EOF);
- break;
- default :
- fprintf(stderr,"Impossible return from menu_data_help_or_abort\n");
- exit(-1);
- }
- }
-
-
- menu_number_help_or_abort (prompt,abortstring,low,high,ptr_ival)
-
- char *prompt, *abortstring;
- int low,high,*ptr_ival;
-
- {
- char *response,errprompt[80],numstring[MAX_MENU_RESPONSE_LENGTH];
- int rval,check;
-
- if (!(check = (low <= high)))
- nbuffconcat(errprompt,1,"Please enter a non-negative number...\n");
- else
- sprintf(errprompt,"Please enter a number between %d and %d\n",low,high);
-
- reask :
-
- rval = menu_data_help_or_abort(prompt,abortstring,&response);
- switch (rval) {
- case MENU_EOF :
- case MENU_ABORT :
- case MENU_HELP :
- return(rval);
- break;
- case MENU_DATA :
- remove_excess_blanks(numstring,response);
- switch (*ptr_ival = str_to_pos_int(numstring,0,MAXINT)) {
- case -1:
- case -2:
- fprintf(stderr,"%s",errprompt);
- goto reask;
- break;
- default:
- return(MENU_DATA);
- break;
- }
- }
-
- }
-
-
- menu_yes_no_abort_or_help (prompt,abortstring,helpallowed,return_for_yes)
-
- /*
- Returns one of MENU_YES, MENU_NO, MENU_ABORT or MENU_HELP.
- If !helpallowed, MENU_HELP will not be returned.
- If return_for_yes is 0, hitting return will re-prompt.
- If it is 1, hitting return is like typing yes.
- If it is any other value, hitting return is like typing no.
- */
-
- char *prompt;
- char *abortstring;
- int helpallowed;
- int return_for_yes;
-
- {
- int menuval,rval;
- char *response;
-
- redo :
-
- if (!helpallowed) {
- rval = menu_match (
- &menuval,&response,
- prompt,
- 0,1,0,0,4,
- "Yes",MENU_YES,
- "No",MENU_NO,
- abortstring,MENU_ABORT,
- "",MENU_RETURN
- );
- }
- else {
- rval = menu_match (
- &menuval,&response,
- prompt,
- 0,1,0,0,6,
- "Yes",MENU_YES,
- "No",MENU_NO,
- "?",MENU_HELP,
- "Help",MENU_HELP,
- abortstring,MENU_ABORT,
- "",MENU_RETURN
- );
- }
- switch (rval) {
- case MENU_MATCH :
- if (menuval != MENU_RETURN) return(menuval);
- switch (return_for_yes) {
- case NO_DEFAULT :
- goto redo;
- break;
- case DEFAULT_YES :
- return(MENU_YES);
- break;
- default :
- return(MENU_NO);
- break;
- }
- break;
- case MENU_NO_MATCH :
- printf("Please type 'Yes' or 'No'...\n");
- goto redo;
- break;
- case MENU_EOF :
- return(MENU_EOF);
- break;
- default :
- fprintf(stderr,"Fatal error: Impossible return in menu_yes_no\n");
- exit(-1);
- }
- }
-
- SHAR_EOF
- if test 7644 -ne "`wc -c < 'toolsdir/menu.c'`"
- then
- echo shar: error transmitting "'toolsdir/menu.c'" '(should have been 7644 characters)'
- fi
- fi
- echo shar: extracting "'toolsdir/menu.h'" '(4423 characters)'
- if test -f 'toolsdir/menu.h'
- then
- echo shar: will not over-write existing file "'toolsdir/menu.h'"
- else
- cat << \SHAR_EOF > 'toolsdir/menu.h'
- /* You must include "<ctools.h>" before including this file. */
-
- #define MENU_EOF -1
- #define MENU_MATCH 0
- #define MENU_AMBIGUOUS 1
- #define MENU_NO_MATCH 2
- #define MENU_ERROR 3
- #define MENU_RETURN 4
-
- #define MAX_MENU_OPTIONS 20
- #define MAX_MENU_RESPONSE_LENGTH 255
-
-
- extern int menu_match();
-
- /* menu_match (
-
- int *ptr_rval,
- char **ptr_user_response,
- char *prompt,
- int case_significant,
- int initial_substring_sufficient,
- int repeat_if_no_match,
- int repeat_if_ambiguous,
- int n_options,
- char *option1, int rval1,
- char *option2, int rval2,
- .
- .
- .
-
- );
-
- Returns one of MENU_MATCH, MENU_AMBIGUOUS, MENU_NO_MATCH, and MENU_ERROR.
- If MENU_MATCH is returned, *ptr_rval contains the value that the caller
- asked to be returned. *ptr_user_response is what exactly what the user
- typed in, minus the linefeed at the end.
-
- prompt is a character string that is printed out. A line of input is
- then read from the terminal, stripped of excess blanks, and compared
- with the menu items. Up to MAX_MENU_OPTIONS can be specified. Each
- option is a character string and has an associated integer return value.
-
- If case_significant is not zero, the user's response will be checked
- against the options with upper/lower case distinction.
- If initial_substring_sufficient is not zero, then a match will occur
- if the user's response is the same as an initial substring of an option,
- otherwise the response must match the option exactly.
-
- If more than one menu option matches the response, MENU_AMBIGUOUS is
- returned. If n_options exceeds MAX_MENU_OPTIONS or the read fails
- MENU_ERROR is returned. If no option matches the response, MENU_NO_MATCH
- is returned. However, if repeat_if_no_match and/or repeat_if_ambiguous
- are non_zero, the user is prompted again until he answers correctly if
- he answers wrongly/ambiguously, respectively.
-
- If "" is not specified as an option, and the user enters a blank line,
- the routine simply prompts the user again. It is impossible to match
- on a string of blanks (e.g., " "), because any blank line the user
- types is considered to be "".
-
- If the response the user types is too long, an error message is printed
- out and the user is asked to try again.
-
- */
-
-
- #define MENU_NO 0
- #define MENU_YES 1
- #define MENU_HELP 2
- #define MENU_ABORT 3
- #define MENU_DATA 4
-
- extern int menu_yes_no();
-
- /* menu_yes_no (prompt,allow_help) char *prompt; int allow_help;
-
- returns one of MENU_NO, MENU_YES or, if help is allowed,
- MENU_HELP. Help can be obtained via "?" or any initial
- substring of "Help", case independently. Returns MENU_EOF
- if end of file encountered when reading.
-
- Yes or no can be obtained via any case independent initial
- substring of "Yes" or "No" respectively.
-
- */
-
-
- #define DEFAULT_YES 0
- #define DEFAULT_NO 1
- #define NO_DEFAULT 2
-
- extern int menu_yes_no_abort_or_help ();
-
- /* menu_yes_no_abort_or_help (prompt,abortstring,helpallowed,return_for_yes)
-
- char *prompt, *abortstring;
- int helpallowed;
- int return_for_yes;
-
- Returns one of MENU_YES, MENU_NO, MENU_ABORT, MENU_HELP or MENU_EOF.
- If !helpallowed, MENU_HELP will not be returned.
- If return_for_yes is DEFAULT_NO, hitting return will re-prompt.
- If it is DEFAULT_YES, hitting return is like typing yes.
- If it is any other value, hitting return is like typing no.
-
- */
-
- extern int menu_data_help_or_abort ();
-
- /*
-
- extern int menu_data_help_or_abort (prompt,abortstring,ptr_response)
-
- char *prompt, *abortstring, **ptr_response;
-
- Returns either MENU_ABORT, MENU_HELP or MENU_DATA. If MENU_DATA is
- returned, *response contains the user's response. MENU_HELP is
- returned in the user types in "?" or any initial substring of "Help"
- (case independently).
-
- */
-
-
- extern int menu_number_help_or_abort ();
-
- /*
- menu_number_help_or_abort (prompt,abortstring,low,high,ptr_ival)
-
- char *prompt; *abortstring;
- int low,high,*ptr_ival;
-
- Returns either MENU_DATA, MENU_ABORT, MENU_HELP or MENU_EOF.
- If low > high any number will be considered valid, otherwise the
- range is checked, inclusivewise. If MENU_DATA is returned, *ptr_ival
- contains the number entered.
-
- At the moment number can only be non-negative.
- */
- SHAR_EOF
- if test 4423 -ne "`wc -c < 'toolsdir/menu.h'`"
- then
- echo shar: error transmitting "'toolsdir/menu.h'" '(should have been 4423 characters)'
- fi
- fi
- echo shar: extracting "'toolsdir/sys5.h'" '(103 characters)'
- if test -f 'toolsdir/sys5.h'
- then
- echo shar: will not over-write existing file "'toolsdir/sys5.h'"
- else
- cat << \SHAR_EOF > 'toolsdir/sys5.h'
- #ifdef SYS5
- #define index(a,b) strchr(a,b)
- #define rindex(a,b) strrchr(a,b)
- #include <string.h>
- #endif
- SHAR_EOF
- if test 103 -ne "`wc -c < 'toolsdir/sys5.h'`"
- then
- echo shar: error transmitting "'toolsdir/sys5.h'" '(should have been 103 characters)'
- fi
- fi
- echo shar: done with directory "'toolsdir'"
- exit 0
- # End of shell archive
-